package io.potato.ts.service;

import io.potato.core.util.AssertUtils;
import io.potato.core.util.TableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 预统计类
 * author: timl
 * time: 2019-4-10 15:57
 */
@Service
@Transactional
@Slf4j
public class SmsStatistic {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static final String STAT_SQL = "insert into \n" +
            "sms_sended_stat \n" +
            "(user_id, user_code, user_type, organ_id, stat_year, stat_month, stat_day, total, success, failed, total1, success1, failed1, total2, success2, failed2, total3, success3, failed3 )\n" +
            "SELECT user_id, t.user_code, t1.user_type, t1.organ_id, " +
            "date_format(send_time, '%Y') st_year, " +
            "date_format(send_time, '%m') st_month, " +
            "date(send_time) st_day,\n" +
            "sum(total) total0, \n" +
            "sum(case when receive_status = 0 then total else 0 end) success, \n" +
            "sum(case when receive_status <> 0 then total else 0 end) failed,\n" +
            "sum(case when dealer_id = 1 then total else 0 end) total1,\n" +
            "sum(case when dealer_id = 1 and receive_status = 0 then total else 0 end) success1, \n" +
            "sum(case when dealer_id = 1 and receive_status <> 0 then total else 0 end) failed1,\n" +
            "sum(case when dealer_id = 2 then total else 0 end) total2,\n" +
            "sum(case when dealer_id = 2 and receive_status = 0 then total else 0 end) success2, \n" +
            "sum(case when dealer_id = 2 and receive_status <> 0 then total else 0 end) failed2,\n" +
            "sum(case when dealer_id = 3 then total else 0 end) total3,\n" +
            "sum(case when dealer_id = 3 and receive_status = 0 then total else 0 end) success3, \n" +
            "sum(case when dealer_id = 3 and receive_status <> 0 then total else 0 end) failed3\n" +
            "FROM {table} t \n" +
            "JOIN t_user t1 on t.user_code = t1.user_code  \n" +
            "where send_time >= ? AND send_time < ? \n" +
            "group by user_code";

    private static final String DEL_SQL = "DELETE FROM sms_sended_stat WHERE stat_day = ?";

    /**
     * 统计指定天的已发短信
     * @param statDay
     */
    public void statSmsSended(LocalDate statDay) {
        AssertUtils.isNotNull(statDay, "statDay can not be null");

        LocalDate start = statDay;
        LocalDate end = statDay.plusDays(1);

        log.warn("start to stat sended for " + start.toString());

        // 删除统计数据
        jdbcTemplate.update(DEL_SQL, statDay);

        doStatSmsSended(start, end);
    }

    /**
     * 统计前一天的已发短信
     */
    public void statSmsSended() {
        statSmsSended(LocalDate.now().minusDays(1));
    }

    private void doStatSmsSended(LocalDate start, LocalDate end) {
        // 统计web用户
        doUpdateSmsSended("sms_sended_record", start, end);

        // API用户
        LocalDateTime startTime = start.atTime(0,0);
        for (int i = 0; i < 10; i++) {
            String tableName = TableUtil.getSendedRecordTable("" + i, startTime);
            doUpdateSmsSended(tableName, start, end);
        }
    }

    private void doUpdateSmsSended(String tableName, LocalDate start, LocalDate end) {
        try {
            String sql = STAT_SQL.replace("{table}", tableName);
            jdbcTemplate.update(sql, start, end);
        } catch (Exception e) {
            log.error("", e);
        }
    }

}
